﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Threading;
using System.IO;
using System.Web;
using System.Windows.Forms;

namespace Comet
{
    class Communications
    {
        public enum DataType { Text, JSON, CSS, Image, GIF, JS }
        public static Dictionary<string, byte[]> webFiles = new Dictionary<string, byte[]>();
        public static Dictionary<string, byte[]> emoticons = new Dictionary<string, byte[]>();


        public Communications()
        {
            LoadWebFiles();
        }

        public static void LoadWebFiles()
        {
            webFiles.Clear();
            foreach (string file in Directory.GetFiles("C:\\comet"))
            {
                webFiles.Add(Path.GetFileName(file), File.ReadAllBytes(file));
            }

            emoticons.Clear();
            foreach (string file in Directory.GetFiles("C:\\comet\\emoticons\\standard"))
            {
                emoticons.Add(Path.GetFileName(file), File.ReadAllBytes(file));
            }

            foreach (string file in Directory.GetFiles("C:\\comet\\emoticons\\extra"))
            {
                emoticons.Add(Path.GetFileName(file), File.ReadAllBytes(file));
            }

        }

        public void serveWebFile(string file, HttpListenerContext context, string urlParams)
        {
            HttpListenerResponse response = context.Response;
            byte[] responseData;
            DataType type = DataType.Text;

            if (file == "")
            {
                responseData = webFiles["index.html"];
            }
            else if (file == "about")
            {
                responseData = webFiles["about.html"];
            }
            else if (file == "home")
            {
                responseData = webFiles["index.html"];
                context.Response.Headers.Add("Set-Cookie", "showhome=true" + Verify.cookieExpireData);
            }
            else if (file == "emoticon")
            {
                if (urlParams != null && emoticons.ContainsKey(urlParams))
                {
                    responseData = emoticons[urlParams];
                }
                else responseData = Encoding.UTF8.GetBytes("none");

                if (urlParams != null && urlParams.Contains(".png")) type = DataType.Image;
                else type = DataType.GIF;
            }
            else if (file == "stats")
            {
                responseData = webFiles["stats.html"];
            }
            else if (file == "statsvalues")
            {
                responseData = Stats.GetStatsString();
            }
            else if (file == "downloadlog")
            {
                Dictionary<string, string> postData = Communications.ParsePost(context);
                if (postData != null && postData.ContainsKey("log"))
                {
                    context.Response.Headers.Add("Content-Disposition", "attachment; filename=\"zuChat conversation log.html\"");
                    responseData = Encoding.UTF8.GetBytes(Encoding.UTF8.GetString(webFiles["log.html"]).Replace("<!--LOGITEMS-->", HttpUtility.UrlDecode(HttpUtility.UrlDecode(postData["log"]))));
                }
                else responseData = webFiles["log.html"];
            }
            else if (webFiles.ContainsKey(file))
            {
                responseData = webFiles[file];
                switch (file.Split('.')[1])
                {
                    case "html":
                        type = DataType.Text;
                        break;
                    case "png":
                        type = DataType.Image;
                        break;
                    case "css":
                        type = DataType.CSS;
                        break;
                    case "js":
                        type = DataType.JS;
                        break;
                }
            }
            else
            {
                responseData = webFiles["none.html"];
            }

            SendResponse(context, type, data: responseData);
        }

        public static Dictionary<string, string> ParsePost(HttpListenerContext context)
        {
            try
            {
                HttpListenerRequest request = context.Request;
                using (StreamReader reader = new StreamReader(request.InputStream))
                {
                    string s2 = reader.ReadToEnd();
                    reader.Close();
                    return Extra.ParseRawParams(s2);

                }
            }
            catch { return null; }
        }

        public static void ReplyCompleted(HttpListenerContext context)
        {
            SendResponse(context, Communications.DataType.Text, "done");
        }

        public static void SendResponse(HttpListenerContext context, DataType type, string message)
        {
            SendResponse(context, type, System.Text.Encoding.UTF8.GetBytes(message));
        }

        static void SendResponse(HttpListenerContext context, DataType type, byte[] data)
        {
            try
            {
                using (HttpListenerResponse response = context.Response)
                {
                    response.ContentLength64 = data.Length;
                    switch (type)
                    {
                        case DataType.CSS:
                            response.ContentType = "text/css";
                            break;
                        case DataType.Image:
                            response.ContentType = "image/png";
                            break;
                        case DataType.GIF:
                            response.ContentType = "image/gif";
                            break;
                        case DataType.JSON:
                            response.ContentType = "application/json";
                            break;
                        case DataType.Text:
                            response.ContentType = "text/html";
                            break;
                        case DataType.JS:
                            response.ContentType = "application/javascript";
                            break;
                    }

                    using (Stream output = response.OutputStream)
                    {
                        Stats.ChatStats.OutboundData += data.Length / 1024;
                        output.Write(data, 0, data.Length);
                        output.Close();
                    }
                }
            }
            catch { }
            finally
            {
                try
                {
                    context.Response.Close();
                }
                catch { }
            }

        }
    }
}
